home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / applic / ncsa / Mac / Telnet2.6 / prerelease / d5 / Telnet 2.6.1d5.src.sit.hqx / Telnet 2.6.1d5 src / source / wdef / wdefpatch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-07  |  12.0 KB  |  466 lines

  1. /*******************************************
  2.  
  3.     WDEF Patcher
  4.     Steve Falkenburg MacDTS
  5.     ⌐1991 Apple Computer
  6.     
  7.     This snippet shows how you can add a simple extra part to a WDEF without
  8.     writing an entire WDEF.  It also shows how to access the new part via
  9.     FindWindow().
  10.     
  11.     Roberto Avanzi (independent programmer), June 18, 1992
  12.     Added support for tracking the extra part, in a way similar to the one used
  13.     by the system.
  14.     given back to Apple as an enhanced snippet (mmmh, sounds quite absurd)
  15.     
  16.     6/1/92    SJF        fixed a5 problem in WDEF patch (StripAddress is glue, and a5 wasn't set up)
  17.     6/1/92    SJF        fixed varCode bug that made zoom boxes not work (masked out high 8 bits)
  18.     
  19. *******************************************/
  20.  
  21. #ifdef MPW
  22. #pragma segment WDEFPatch
  23. #endif
  24.  
  25. #include "TelnetHeader.h"
  26. #include "general_resrcdefs.h"
  27. #include <Gestalt.h>
  28. #ifdef THINK_C
  29. #include <SysEqu.h>
  30. #endif
  31. #include "wind.h"
  32. #include "wdefpatch.proto.h"
  33. #include "tnae.h"
  34.  
  35. static void drawicon(short id, Rect *dest);
  36.  
  37. /* 931112, ragge, NADA, KTH */
  38. static void drawSize(Rect *wSize, WindowPtr window);
  39.  
  40. /* add 2 to this when checking with FindWindow() ! */
  41.  
  42. #define kOurHit    32
  43.  
  44.  
  45. /* 
  46.  * this struct allows us to insert a WDEF patch safely.  It contains a jump instruction
  47.  * and stores the old handle to the WDEF
  48.  */
  49.  
  50. typedef struct {
  51. #ifdef __powerpc__
  52.     RoutineDescriptor rd;
  53. #else
  54.     short jmpInst;
  55.     ProcPtr patchAddr;
  56. #endif
  57.     Handle oldAddr;
  58.     Boolean partState;    /* roberto avanzi jun 18 1992 */
  59.     long ourA5;
  60.     struct WindRec *tw;
  61. } WDEFPatch, *WDEFPatchPtr, **WDEFPatchHndl;
  62.  
  63.  
  64. /* 
  65.  * RePatchWindowWDEF
  66.  * this adjusts the tw pointer for a patched window
  67.  * We have to do this since the tw for a window can change when other
  68.  * windows are killed.
  69.  */
  70. void RePatchWindowWDEF (WindowPtr window, struct WindRec *tw)
  71. {
  72.     WDEFPatchHndl wdPatch;
  73.  
  74.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  75.     (**wdPatch).tw = tw;
  76. }
  77.  
  78.  
  79. /*
  80.  * GetPatchStuffHandle
  81.  * This returns the handle to our patch block so we can release it
  82.  * when killing windows. The tw is verified to insure that this
  83.  * window is really patched.
  84.  */
  85. Handle GetPatchStuffHandle (WindowPtr window, struct WindRec *tw)
  86. {
  87.     WDEFPatchHndl wdPatch;
  88.  
  89.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  90.     if ((**wdPatch).tw == tw)
  91.         return ((Handle)wdPatch);
  92.     else
  93.         return ((Handle)0);
  94. }
  95.  
  96.  
  97. #ifdef __powerpc__
  98. enum {
  99.     uppMyWDEFPatch = kPascalStackBased
  100.         | RESULT_SIZE(SIZE_CODE(sizeof(long)))
  101.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))
  102.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr)))
  103.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short)))
  104.         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
  105. };
  106. #endif
  107.  
  108. pascal long MyWDEFPatch (short varCode, WindowPtr window, short message, long param)
  109. {
  110.     WDEFPatchHndl wdPatch;
  111.     pascal long (*wdefProc)(short varCode,WindowPtr window,short message,long param);
  112.     Handle oldWDEF;
  113.     long result;
  114.     Rect ourRect,ourElementRect;
  115.     GrafPtr    savePort;
  116.     GrafPtr aPort;
  117.     RgnHandle aRgn;
  118.     Rect aRect;
  119.     struct WindRec *tw;
  120.     long appA5, saveA5;
  121.     
  122.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  123.     appA5 = (**wdPatch).ourA5;
  124.     saveA5 = SetA5(appA5);
  125.  
  126.     ourRect = (**((WindowPeek)window)->strucRgn).rgnBBox;
  127.     /* our 16x16 rectangle */
  128.     SetRect(&ourElementRect,ourRect.right-42,ourRect.top+1,ourRect.right-26,ourRect.top+17);
  129.     
  130.     tw = (**wdPatch).tw;
  131.  
  132.     oldWDEF = (**wdPatch).oldAddr;
  133.     HLock(oldWDEF);
  134.     wdefProc = (void *)*oldWDEF;
  135.     wdefProc = (void *)StripAddress(wdefProc);
  136.  
  137.     /* 
  138.      * now, folks, WHY do I check it, u'll ask me ? Heh, it's a funny quirk in
  139.      * the sys WDEF (at least, sys 7's, dunno whattabout older ones) .
  140.      * Suppose You click once in the grow icon and DO NOT resize the window.
  141.      * (remember, just click and do not move the mouse in the meantime).
  142.      * Then you click on the added part. That part is tracked in the right way,
  143.      *                             *    BUT   *
  144.      * ALSO the zoom box gets hilited. Dunno why should happen, but It's a lot
  145.      * of FUN. Sadly, cannot find its place in any useful app. Therefore we
  146.      * do this check.
  147.      * APPLE says: if you write your own WDEF and receive unknown messages, do not
  148.      *             do anything. pass along and do NOTHING.
  149.      * APPLE does: we get something new ? therefore we process it anyway, just to
  150.      *             keep developers writing workarounds and keep their minds afresh.
  151.      * What else can we say ? Thanks !!!!! (Roberto Avanzi june 19, 1992)
  152.      */
  153.     if ( (message == wDraw) ? (((short)param) != kOurHit ) : true ) {
  154. #ifdef __powerpc__
  155.         result = CallUniversalProc((UniversalProcPtr)wdefProc, uppMyWDEFPatch, varCode, window, message, param);
  156. #else
  157.         result = (wdefProc)(varCode,window,message,param);
  158. #endif
  159.     }
  160.  
  161.     if (((WindowPeek)window)->visible)
  162.     if (((WindowPeek)window)->hilited)
  163.     {
  164.         switch (message) {
  165.             case wDraw:
  166.                 GetPort(&savePort);
  167.                 GetWMgrPort(&aPort);
  168.                 SetPort(aPort);
  169.                 aRgn = NewRgn();
  170.                 GetClip(aRgn);
  171.                 SetRect(&aRect,-32000,-32000,32000,32000);
  172.                 ClipRect(&aRect);
  173.                 switch ( (short) param ) {    // Roberto Avanzi 18-06-1992: support for 
  174.                                             // tracking of the new part
  175.                     case 0:
  176.                         (**wdPatch).partState = false;
  177.  
  178.                     case kOurHit:
  179.                         PenNormal();                            // draw our part
  180.     
  181.                          if (tw->aedata != NULL) {
  182.                             tnParams *ae = (tnParams *)tw->aedata;
  183.  
  184.                              if (ae->encrypting || ae->decrypting) {
  185.                                  /* 
  186.                                   * erase 18 x 11. This gives us a 1 pixel margin
  187.                                   * on the left and right, and matches the mask that
  188.                                   * we're using in our crsr resources.
  189.                                   */
  190.                                  InsetRect(&ourElementRect, -1, 0);
  191.                                  ourElementRect.top += 3;
  192.                                  ourElementRect.bottom -= 2;
  193.                                  EraseRect(&ourElementRect);
  194.                                  ourElementRect.top -= 3;
  195.                                  ourElementRect.bottom += 2;
  196.                                  InsetRect(&ourElementRect, 1, 0);
  197.                              }                        
  198.                              if (ae->encrypting && ae->decrypting)
  199.                                  drawicon(lockcrsr, &ourElementRect);
  200.                              else if (ae->encrypting)
  201.                                  drawicon(rightcrsr, &ourElementRect);
  202.                              else if (ae->decrypting)
  203.                                  drawicon(leftcrsr, &ourElementRect);
  204.                          }
  205.                         break;
  206.                         
  207.                     default:
  208.                         break;
  209.                 }
  210.                 SetClip(aRgn);
  211.                 DisposeRgn(aRgn);
  212.                 SetPort(savePort);
  213.                 break;
  214.  
  215.                 // removed this test so that one can move the window
  216.                 // also when clicking on the icon area.
  217.                 // 931112, ragge, NADA, KTH
  218. #ifdef NOTDEF
  219.             case wHit:
  220.                 hitPt = (Point *)¶m;                    // hit test our part
  221.                 if (PtInRect(*hitPt,&ourElementRect))
  222.                 {
  223.                     //result =  kOurHit;
  224.                 }
  225.                 break;
  226. #endif
  227.             
  228.             case wGrow:        /* 931112, ragge, NADA, KTH */
  229.                 drawSize((Rect *) param, window);
  230.                 break;
  231.  
  232.             default:
  233.                 break;
  234.         }    // switch
  235.     }    //    if hilited (otherwise we dont see the new box, addition by Roberto Avanzi)
  236.     HUnlock(oldWDEF);
  237.     
  238.     SetA5(saveA5);
  239.     
  240.     return result;
  241. }
  242.  
  243.  
  244. #ifdef __powerpc__
  245. RoutineDescriptor MyWDEFPatchUniversal = BUILD_ROUTINE_DESCRIPTOR(uppMyWDEFPatch, MyWDEFPatch);
  246. #endif
  247.  
  248. /* 
  249.  * this installs the WDEF patch into a window 
  250.  */
  251. void PatchWindowWDEF (WindowPtr window, struct WindRec *tw)
  252. {
  253.     WDEFPatchHndl wdefHndl;
  254.     WDEFPatchPtr wdefPatch;
  255.     Handle oldAddr;
  256.     unsigned long wdefEntry;
  257.     
  258.     wdefHndl = (WDEFPatchHndl)NewHandle(sizeof(WDEFPatch));
  259.  
  260.     oldAddr = ((WindowPeek)window)->windowDefProc;
  261.     if (GetMMUMode()) // 32-bit
  262.         wdefEntry = (unsigned long)wdefHndl;
  263.     else
  264.         wdefEntry = (unsigned long)StripAddress(wdefHndl) | ((unsigned long)oldAddr&0xff000000);
  265.  
  266.     HLock((Handle)wdefHndl);
  267.     wdefPatch = *wdefHndl;
  268.     wdefPatch->oldAddr = oldAddr;
  269. #ifdef __powerpc__
  270.     BlockMove(&MyWDEFPatchUniversal, &wdefPatch->rd, sizeof(wdefPatch->rd));
  271. #else
  272.     wdefPatch->jmpInst = 0x4ef9; /*JMP*/
  273.     wdefPatch->patchAddr = (ProcPtr)MyWDEFPatch;
  274. #endif
  275.     wdefPatch->ourA5 = (long)LMGetCurrentA5();        /* Use universal access (RW) */
  276.     wdefPatch->tw = tw;
  277.  
  278.     HUnlock((Handle)wdefHndl);
  279.  
  280.     ((WindowPeek)window)->windowDefProc = (Handle)wdefEntry;
  281. }
  282.  
  283.  
  284. /*
  285.  * drawicon
  286.  */
  287. void drawicon (short id, Rect *dest)
  288. {
  289.     long qdv;
  290.     Handle ih = 0;
  291.     Rect source_rect;
  292.     BitMap mask_bitmap;
  293.     GrafPtr local_port;
  294.     PixMap *pm;
  295.     Ptr colormap;
  296.     CCrsr *ccrsr;
  297.     BitMap src_bitmap;
  298.  
  299.     GetPort(&local_port);
  300.  
  301.     ih = GetResource ('crsr', id);                /* color cursor */
  302.     if (!ih)
  303.         return;
  304.     DetachResource(ih);        /* ... need to save handle somewhere ... */
  305.     HLock(ih);                /* ... to avoid reloading the resource all the time */
  306.  
  307.     /* 
  308.      * Set source Rect and intialize source BitMaps. 
  309.      * A few PixMap fields must be munged;
  310.      */
  311.     SetRect (&source_rect, 0, 0, 16, 16);
  312.     
  313.     ccrsr = (CCrsr *)(*ih);
  314.  
  315.     mask_bitmap.bounds = source_rect;
  316.     mask_bitmap.rowBytes = 2;
  317.     mask_bitmap.baseAddr = (Ptr)&ccrsr->crsrMask; /* (Ptr)(((Byte *)(*ih)) + 52); */
  318.     
  319.     /*
  320.      * if gestalt fails or no color quickdraw, just use the b/w bitmap.
  321.      */
  322.     if (Gestalt(gestaltQuickdrawVersion, &qdv) || ((qdv & gestalt32BitQD) == 0)) {
  323.         src_bitmap.bounds = source_rect;
  324.         src_bitmap.rowBytes = 2;
  325.         src_bitmap.baseAddr = (Ptr)&ccrsr->crsr1Data;
  326.         CopyBits(&src_bitmap, &(local_port->portBits), &source_rect, dest,
  327.                  srcCopy, nil);    
  328.     } else {
  329.         pm = (PixMap *) ((unsigned char *)ccrsr + (long)ccrsr->crsrMap);
  330.         pm->baseAddr = (Ptr) ((unsigned char *)ccrsr + (long)ccrsr->crsrData);
  331.             colormap = (Ptr) ((unsigned char *)ccrsr + (long)pm->pmTable);
  332.         pm->pmTable = (CTabHandle) &colormap;        /* handle to colormap */
  333.  
  334.         /* 
  335.          * Draw the crsr using its mask. 
  336.          * Do we need the mask ??? ...
  337.          */
  338.         CopyMask((BitMap *)pm, &mask_bitmap, &(local_port->portBits),
  339.                  &source_rect, &source_rect, dest);
  340.     }
  341.  
  342. //    HUnlock(ih);
  343. //    ReleaseResource((Handle)ih);
  344.     DisposHandle((Handle)ih);
  345. }
  346.  
  347. /* 931112, ragge, NADA, KTH */
  348. #define    HOFFSET    2
  349. #define VOFFSET    2
  350. static Rect gGrowTextBox;
  351. static Rect gGrowTextBoxInset;
  352. Boolean gDoGrowSize = false;
  353. static struct growSavedStruct {
  354.     Point charSize;
  355.     Point charInset;
  356.     Boolean eraseIt;
  357.  
  358.     PenState    savedPen;
  359.     short txFont;
  360.     Style txFace;
  361.     short txMode;
  362.     short txSize;
  363. } gGrowSaved;
  364.  
  365. /* 931112, ragge, NADA, KTH */
  366. void setupForGrow(WindowPtr window, short hCharInset, short vCharInset, short hCharSize, short vCharSize)
  367. {
  368.     GrafPtr    savedPort;
  369.     FontInfo fInfo;
  370.  
  371.     GetPort(&savedPort);
  372.     SetPort(window);
  373.         
  374.     gGrowSaved.charSize.h = hCharSize;
  375.     gGrowSaved.charSize.v = vCharSize;
  376.     gGrowSaved.charInset.h = hCharInset;
  377.     gGrowSaved.charInset.v = vCharInset;
  378.  
  379.     if(gGrowSaved.charSize.h == 0)    // don't want zero-div
  380.         gGrowSaved.charSize.h = 1;
  381.     if(gGrowSaved.charSize.v == 0)
  382.         gGrowSaved.charSize.v = 1;
  383.         
  384.     gGrowSaved.eraseIt = false;
  385.     
  386.     GetPenState(&gGrowSaved.savedPen);
  387.     
  388.     gGrowSaved.txFont = window->txFont;
  389.     gGrowSaved.txFace = window->txFace;
  390.     gGrowSaved.txMode = window->txMode;
  391.     gGrowSaved.txSize = window->txSize;
  392.  
  393.     PenNormal();
  394.     TextFont(1);
  395.     TextSize(9);
  396.     TextFace(0);
  397.     TextMode(srcCopy);
  398.     
  399.     GetFontInfo(&fInfo);
  400.  
  401.     gGrowTextBox.top = VOFFSET;
  402.     gGrowTextBox.left = HOFFSET;
  403.     gGrowTextBox.bottom = VOFFSET + fInfo.ascent + fInfo.descent + fInfo.leading + 3;    // Yes, 3!
  404.     gGrowTextBox.right = HOFFSET + StringWidth("\p000 * 000") + 6;
  405.     gGrowTextBoxInset = gGrowTextBox;
  406.     InsetRect(&gGrowTextBoxInset, 1, 1);
  407.     
  408.     gDoGrowSize = true;
  409.     
  410.     SetPort(savedPort);
  411. }
  412.  
  413. /* 931112, ragge, NADA, KTH */
  414. void cleanupForGrow(WindowPtr window)
  415. {
  416.     GrafPtr    savedPort;
  417.     GetPort(&savedPort);
  418.     SetPort(window);
  419.     
  420.     gDoGrowSize = false;
  421.     
  422.     InvalRect(&gGrowTextBox);
  423.     
  424.     SetPenState(&gGrowSaved.savedPen);
  425.     
  426.     window->txFont = gGrowSaved.txFont;
  427.     window->txFace = gGrowSaved.txFace;
  428.     window->txMode = gGrowSaved.txMode;
  429.     window->txSize = gGrowSaved.txSize;
  430.     
  431.     SetPort(savedPort);
  432. }
  433.  
  434. /* 931112, ragge, NADA, KTH */
  435. void drawSize(Rect *wSize, WindowPtr window)
  436. {
  437.     unsigned char string[50], yValLen;
  438.     GrafPtr savedPort;
  439.     
  440.     if(!gDoGrowSize)
  441.         return;
  442.  
  443.     GetPort(&savedPort);
  444.     SetPort(window);
  445.     
  446.     if(!gGrowSaved.eraseIt) {
  447.         NumToString((wSize->right - wSize->left - 15 - gGrowSaved.charInset.h) / gGrowSaved.charSize.h, string);
  448.         string[++string[0]] = ' ';
  449.         string[++string[0]] = '*';
  450.         NumToString((wSize->bottom - wSize->top - 15 - gGrowSaved.charInset.v) / gGrowSaved.charSize.v, string + string[0] + 1);
  451.         yValLen = string[string[0] + 1];
  452.         string[++string[0]] = ' ';
  453.         string[0] += yValLen;
  454.         TextBox(string + 1, string[0], &gGrowTextBoxInset, 1);
  455.         FrameRect(&gGrowTextBox);
  456.     } else {
  457.         Rect rGlob = gGrowTextBox;
  458.         LocalToGlobal((Point *) &(rGlob.top));
  459.         LocalToGlobal((Point *) &(rGlob.bottom));
  460.     }
  461.     
  462.     gGrowSaved.eraseIt = !gGrowSaved.eraseIt;
  463.  
  464.     SetPort(savedPort);
  465. }
  466.